import axios$1 from 'axios';
import Cookies from 'js-cookie';

const tempDevice = {};
const userAgent = window.navigator.userAgent.toLowerCase();
const television = [
    'googletv',
    'viera',
    'smarttv',
    'internet.tv',
    'netcast',
    'nettv',
    'appletv',
    'boxee',
    'kylo',
    'roku',
    'dlnadoc',
    'pov_tv',
    'hbbtv',
    'ce-html',
];
tempDevice.macos = function () {
    return find('mac');
};
tempDevice.ios = function () {
    return tempDevice.iphone() || tempDevice.ipod() || tempDevice.ipad();
};
tempDevice.iphone = function () {
    return !tempDevice.windows() && find('iphone');
};
tempDevice.ipod = function () {
    return find('ipod');
};
tempDevice.ipad = function () {
    const iPadOS13Up = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1;
    return find('ipad') || iPadOS13Up;
};
tempDevice.android = function () {
    return !tempDevice.windows() && find('android');
};
tempDevice.androidPhone = function () {
    return tempDevice.android() && find('mobile');
};
tempDevice.androidTablet = function () {
    return tempDevice.android() && !find('mobile');
};
tempDevice.blackberry = function () {
    return find('blackberry') || find('bb10');
};
tempDevice.blackberryPhone = function () {
    return tempDevice.blackberry() && !find('tablet');
};
tempDevice.blackberryTablet = function () {
    return tempDevice.blackberry() && find('tablet');
};
tempDevice.windows = function () {
    return find('windows');
};
tempDevice.windowsPhone = function () {
    return tempDevice.windows() && find('phone');
};
tempDevice.windowsTablet = function () {
    return tempDevice.windows() && find('touch') && !tempDevice.windowsPhone();
};
tempDevice.fxos = function () {
    return (find('(mobile') || find('(tablet')) && find(' rv:');
};
tempDevice.fxosPhone = function () {
    return tempDevice.fxos() && find('mobile');
};
tempDevice.fxosTablet = function () {
    return tempDevice.fxos() && find('tablet');
};
tempDevice.meego = function () {
    return find('meego');
};
tempDevice.mobile = function () {
    return (tempDevice.androidPhone() ||
        tempDevice.iphone() ||
        tempDevice.ipod() ||
        tempDevice.windowsPhone() ||
        tempDevice.blackberryPhone() ||
        tempDevice.fxosPhone() ||
        tempDevice.meego());
};
tempDevice.tablet = function () {
    return (tempDevice.ipad() ||
        tempDevice.androidTablet() ||
        tempDevice.blackberryTablet() ||
        tempDevice.windowsTablet() ||
        tempDevice.fxosTablet());
};
tempDevice.desktop = function () {
    return !tempDevice.tablet() && !tempDevice.mobile();
};
tempDevice.television = function () {
    let i = 0;
    while (i < television.length) {
        if (find(television[i])) {
            return true;
        }
        i++;
    }
    return false;
};
function includes(haystack, needle) {
    return haystack.indexOf(needle) !== -1;
}
function find(needle) {
    return includes(userAgent, needle);
}
function findMatch(arr) {
    for (let i = 0; i < arr.length; i++) {
        if (tempDevice[arr[i]]()) {
            return arr[i];
        }
    }
    return 'unknown';
}
const device = {
    type: 'unknown',
    os: 'unknown',
};
device.type = findMatch(['mobile', 'tablet', 'desktop']);
device.os = findMatch([
    'ios',
    'iphone',
    'ipad',
    'ipod',
    'android',
    'blackberry',
    'macos',
    'windows',
    'fxos',
    'meego',
    'television',
]);

/******************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */

function __awaiter(thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
}

const tokenKey = 'token';
const userIdKey = 'userId';
const suffix = 'monitor-sdk';
function resolveName(prefix) {
    return `${prefix}_${suffix}`;
}
function getToken() {
    return Cookies.get(resolveName(tokenKey));
}
function setToken(token) {
    return Cookies.set(resolveName(tokenKey), token);
}
function getUserId() {
    return Cookies.get(resolveName(userIdKey));
}
function setUserId(userId) {
    return Cookies.set(resolveName(userIdKey), userId);
}

// 后端定义的状态code值
const STATUS_CODE_SUCCESS = 0;
// 驼峰转下划线
const hump2Line = (str) => str.replace(/[A-Z]/g, match => `_${match.toLowerCase()}`);
// 下划线转驼峰
const line2Hump = (str) => str.replace(/_(\w)/g, (all, letter) => letter.toUpperCase());
const getKey = (key, is2Hump) => (is2Hump ? line2Hump(key) : hump2Line(key));
// 深拷贝转换驼峰或者下划线
const obj2HumpOrLine = (obj, is2Hump) => {
    if (typeof obj === 'string' && !is2Hump) {
        const result = obj.split('&').map(p => {
            const key = p.split('=')[0];
            const value = p.split('=')[1];
            const tempKey = hump2Line(key);
            return `${tempKey}=${value}`;
        });
        return result.join('&');
    }
    const objClone = Array.isArray(obj) ? [] : {};
    if (obj && typeof obj === 'object') {
        for (const key in obj) {
            if (key) {
                const tempKey = getKey(key, is2Hump);
                objClone[tempKey] =
                    typeof obj[key] === 'object' && obj[key] ? obj2HumpOrLine(obj[key], is2Hump) : obj[key];
            }
        }
    }
    return objClone;
};
class HttpRequest {
    constructor(baseURL) {
        Object.defineProperty(this, "request", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        const instance = axios$1.create({
            baseURL,
        });
        // 请求拦截器
        instance.interceptors.request.use(config => {
            var _a, _b;
            const { params, data } = config;
            if (data instanceof FormData) {
                return config;
            }
            params && (config.params = obj2HumpOrLine(params, false));
            data && (config.data = obj2HumpOrLine(data, false));
            if (config && config.headers) {
                config.headers['token'] = (_a = getToken()) !== null && _a !== void 0 ? _a : '';
                config.headers['userId'] = (_b = getUserId()) !== null && _b !== void 0 ? _b : '';
            }
            return config;
        }, error => Promise.reject(error));
        // 响应拦截器
        instance.interceptors.response.use(response => response, error => {
            const { response: { status }, } = error;
            const errorMsg = {
                403: 'Server rejected the request!',
                404: '404 Not Found!',
                500: 'Server Error!',
            }[status] || 'Server Error!';
            return errorMsg;
        });
        const request = (config) => __awaiter(this, void 0, void 0, function* () {
            const { data } = yield instance.request(config);
            const { data: responseData, statusCode, statusMsg } = obj2HumpOrLine(data, true);
            if (statusCode !== STATUS_CODE_SUCCESS) {
                return Promise.reject(statusMsg);
            }
            else {
                return responseData;
            }
        });
        this.request = request;
    }
}

/**
 * 登录
 * @returns 返回userId和token
 */
const sendLogApi = (data) => axios({
    method: 'POST',
    url: '/assemble/sdk/v1/metric',
    data: Object.assign({}, data),
});
const sendElkApi = (data) => axios({
    method: 'POST',
    url: '/elk/log',
    data: Object.assign({}, data),
});

let httpRequest = null;
const axios = (config) => httpRequest && httpRequest(config);
const initHttp = (baseUrl) => {
    httpRequest = new HttpRequest(baseUrl).request;
};

var ServerLogType;
(function (ServerLogType) {
    ServerLogType["counter"] = "counter";
    ServerLogType["guage"] = "gauge";
    ServerLogType["timer"] = "timer";
})(ServerLogType || (ServerLogType = {}));
var MsgType;
(function (MsgType) {
    MsgType["text"] = "text";
    MsgType["count"] = "count";
    MsgType["time"] = "time";
    MsgType["max"] = "max";
    MsgType["min"] = "min";
    MsgType["average"] = "average";
    MsgType["object"] = "object";
})(MsgType || (MsgType = {}));
var LogType;
(function (LogType) {
    LogType["error"] = "error";
    LogType["warn"] = "warn";
    LogType["info"] = "info";
})(LogType || (LogType = {}));
var VisualLogType;
(function (VisualLogType) {
    VisualLogType[VisualLogType["console"] = 0] = "console";
    VisualLogType[VisualLogType["page"] = 1] = "page";
})(VisualLogType || (VisualLogType = {}));

const VTUBER_MONITOR_KEY = '__vtuber_monitor_log';
const MAX_LENGTH = 30;
const MAX_PER_LENGTH = 100;
const MAX_DAYS = 30;
const ONE_DAY = 1000 * 60 * 60 * 24;
const DEFAULT_SEND_TIME = 1000 * 60 * 5;
const AnyToString = (data) => typeof data === 'object' ? JSON.stringify(data) : String(data);
const handleAverage = (oldAverage, oldCount, newNumber) => (oldAverage * oldCount + newNumber) / (oldCount + 1);
const handleMax = (num1, num2) => Math.max(num1, num2);
const handleMin = (num1, num2) => Math.min(num1, num2);
const VTUBER_MONITOR_OPEN_KEY = 'vtuber_monitor';
const VTUBER_MONITOR_OPEN_VALUE = 'nxrzt';
const getQueryString = () => {
    const search = window.location.hash.split('?')[1] || window.location.search.substr(1);
    const reg = new RegExp('(^|&)' + VTUBER_MONITOR_OPEN_KEY + '=([^&]*)(&|$)');
    const r = search.match(reg);
    if (r !== null)
        return unescape(r[2]) === VTUBER_MONITOR_OPEN_VALUE;
    return false;
};

class LocalStorage {
    constructor(_storageOption, _createTime) {
        Object.defineProperty(this, "_storageOption", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: _storageOption
        });
        Object.defineProperty(this, "_createTime", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: _createTime
        });
        Object.defineProperty(this, "_currentStorageData", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "_historyStorageData", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "_historyneedSendServerData", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: []
        });
        this._currentStorageData = [];
        this._historyStorageData = this._getItem();
        this._handleHistoryData(_storageOption.localStorageMaxDay);
        this._setItem();
    }
    _handleHistoryData(maxDay) {
        const keys = Object.keys(this._historyStorageData).sort((a, b) => +b - +a);
        const length = keys.length;
        for (let i = 0; i < length; i++) {
            const key = keys[i];
            this._historyStorageData[key].forEach(logInfo => {
                if (logInfo.nextSend) {
                    logInfo.nextSend = false;
                    logInfo.needSendServer = true;
                }
                if (logInfo.needSendServer) {
                    this._historyneedSendServerData.push(logInfo);
                }
            });
            // 删除过期历史数据
            if (Number(this._createTime) >= Number(key) + maxDay * ONE_DAY ||
                this._historyStorageData[key].length === 0 ||
                i >= this._storageOption.localStorageMaxLength) {
                delete this._historyStorageData[key];
            }
        }
    }
    _getItem() {
        return JSON.parse(localStorage.getItem(this._storageOption.localStorageKey) || '{}');
    }
    _setItem() {
        try {
            localStorage.setItem(this._storageOption.localStorageKey, JSON.stringify(Object.assign(Object.assign({}, this._historyStorageData), { [this._createTime]: this._currentStorageData })));
        }
        catch (_a) {
            this._historyStorageData = {};
        }
    }
    saveData() {
        this._setItem();
    }
    _beforeAddData(value) {
        var _a, _b, _c;
        var _d;
        const lastIndex = this._currentStorageData.findIndex(item => {
            return (item.msg.serveKey === value.msg.serveKey &&
                JSON.stringify(item.msg.serverTag) === JSON.stringify(value.msg.serverTag));
        });
        let isNumber = false;
        let number = 0;
        let msg = 0;
        if (lastIndex !== -1) {
            msg = this._currentStorageData[lastIndex].msg.msg;
            number = (_b = ((_a = this._currentStorageData[lastIndex].msg.msgTip) !== null && _a !== void 0 ? _a : {}).__count) !== null && _b !== void 0 ? _b : 0;
        }
        number++;
        switch (value.msg.msgType) {
            // 平均值和时间都取均值
            case MsgType.average:
            case MsgType.time:
                value.msg.msg = handleAverage(msg, number - 1, value.msg.msg);
                isNumber = true;
                break;
            // 累计值
            case MsgType.count:
                value.msg.msg += msg;
                isNumber = true;
                break;
            // 最大值
            case MsgType.max:
                value.msg.msg = handleMax(value.msg.msg, msg);
                isNumber = true;
                break;
            // 最小值
            case MsgType.min:
                value.msg.msg = handleMin(value.msg.msg, msg);
                isNumber = true;
                break;
        }
        if (isNumber && lastIndex !== -1) {
            this._currentStorageData.splice(lastIndex, 1);
            (_c = (_d = value.msg).msgTip) !== null && _c !== void 0 ? _c : (_d.msgTip = {});
            value.msg.msgTip.__count = number;
        }
    }
    addData(value) {
        this._beforeAddData(value);
        this._currentStorageData.push(value);
        if (this._currentStorageData.length >= this._storageOption.localStorageMaxPerLength) {
            this._currentStorageData.shift();
        }
    }
    getHistoryneedSendServerData() {
        return this._historyneedSendServerData;
    }
    getNeedSendData() {
        return this._currentStorageData.filter(item => item.needSendServer);
    }
    getAllData() {
        return Object.assign(Object.assign({}, this._historyStorageData), { [this._createTime]: this._currentStorageData });
    }
}

const timestampToTime = (timestamp) => {
    const date = new Date(timestamp);
    const _10 = 10;
    const Y = date.getFullYear();
    const M = date.getMonth() + 1 < _10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1;
    const D = date.getDate() < _10 ? `0${date.getDate()}` : date.getDate();
    const h = date.getHours() < _10 ? `0${date.getHours()}` : date.getHours();
    const m = date.getMinutes() < _10 ? `0${date.getMinutes()}` : date.getMinutes();
    const s = date.getSeconds() < _10 ? `0${date.getSeconds()}` : date.getSeconds();
    return `${Y}-${M}-${D} ${h}:${m}:${s}`;
};
const handleLogInfoData = (data) => data.map(item => {
    const temp = {};
    temp.time = timestampToTime(item.time);
    temp.logType = item.logType;
    temp.msg = AnyToString(item.msg.msg);
    temp.msgType = item.msg.msgType;
    temp.serveKey = item.msg.serveKey;
    temp.msgTip = AnyToString(item.msg.msgTip);
    return temp;
});

const wrapTh = (str) => `<th style="padding: 8px 12px;">${str}</th>`;
const wrapTd = (str) => `<td style="padding: 8px 12px;border: 1px solid #333;">${str}</td>`;
const wrapRow = (data, keys, index) => `
  <tr>
    ${wrapTd(String(index + 1))}
    ${keys.map(key => wrapTd(data[key])).join('')}
  </tr>
`;
const createTable = (data) => {
    const keys = data[0] ? Object.keys(data[0]) : [];
    const tableStr = `
    <table style="border: 1px solid #333;">
      <thead style="color: #fff; background-color: #333; font-weight: 600;">
        <tr>
          ${wrapTh('序号')}
          ${keys.map(wrapTh).join('')}
        </tr>
      </thead>
      <tbody>
        ${data.map((item, index) => wrapRow(item, keys, index)).join('')}
      </tbody>
    </table>
  `;
    const tableBox = document.createElement('div');
    tableBox.innerHTML = tableStr;
    return tableBox;
};
const createButton = (click) => {
    const buttonDom = document.createElement('button');
    buttonDom.innerText = '关闭';
    buttonDom.onclick = () => click();
    return buttonDom;
};
const createSelect = (keys, currentKey, cb) => {
    const selectDom = document.createElement('select');
    keys.forEach(key => {
        const optionDom = document.createElement('option');
        optionDom.value = key;
        optionDom.innerText = timestampToTime(Number(key));
        if (key === currentKey) {
            optionDom.setAttribute('selected', 'true');
        }
        selectDom.appendChild(optionDom);
    });
    selectDom.onchange = () => {
        cb(selectDom.value);
    };
    return selectDom;
};
let tableDom;
const createTableBox = (data, currentKey) => {
    const boxDom = document.createElement('div');
    boxDom.style.position = 'fixed';
    boxDom.style.background = '#fff';
    boxDom.style.zIndex = '9999';
    boxDom.style.left = '0';
    boxDom.style.bottom = '0';
    boxDom.style.width = '100vw';
    boxDom.style.height = '50vh';
    boxDom.style.overflow = 'auto';
    boxDom.appendChild(createSelect(Object.keys(data), currentKey, (key) => {
        if (tableDom) {
            boxDom.removeChild(tableDom);
        }
        tableDom = createTable(handleLogInfoData(data[key]));
        boxDom.appendChild(tableDom);
    }));
    boxDom.appendChild(createButton(() => {
        document.body.removeChild(boxDom);
    }));
    tableDom = createTable(handleLogInfoData(data[currentKey]));
    boxDom.appendChild(tableDom);
    document.body.append(boxDom);
};

const logVisualDataInConsoleOne = (data, key) => {
    if (data[key]) {
        console.log(key);
        console.table(handleLogInfoData(data[key]));
    }
    else {
        console.log(`no ${key}`);
    }
};
const logVisualDataInConsole = (data, currentKey) => {
    console.log('history time', Object.keys(data));
    console.log('current');
    console.table(handleLogInfoData(data[currentKey]));
};
const logVisualDataInPage = (data, currentKey) => {
    createTableBox(data, currentKey);
};
const logVisualDataFuncs = {
    [VisualLogType.console]: logVisualDataInConsole,
    [VisualLogType.page]: logVisualDataInPage,
};
const logVisualData = (data, currentKey, type) => {
    return logVisualDataFuncs[type](data, currentKey);
};

class MonitorSDK {
    constructor(loginConfig) {
        var _a, _b, _c, _d, _e, _f;
        Object.defineProperty(this, "_createTime", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "_localStorage", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "_metrixPrefix", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "_sendTime", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "_interval", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "_noElk", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: false
        });
        this._initHttp(loginConfig.baseUrl);
        this._setUserIdAndToken(loginConfig.userId, loginConfig.token);
        this._createTime = String(+new Date());
        this._localStorage = new LocalStorage({
            localStorageKey: (_a = loginConfig.localStorageKey) !== null && _a !== void 0 ? _a : VTUBER_MONITOR_KEY,
            localStorageMaxDay: (_b = loginConfig.localStorageMaxDay) !== null && _b !== void 0 ? _b : MAX_DAYS,
            localStorageMaxPerLength: (_c = loginConfig.localStorageMaxPerLength) !== null && _c !== void 0 ? _c : MAX_PER_LENGTH,
            localStorageMaxLength: (_d = loginConfig.localStorageMaxLength) !== null && _d !== void 0 ? _d : MAX_LENGTH,
        }, this._createTime);
        this._metrixPrefix = loginConfig.vtuberMetricPrefix;
        this._sendTime = (_e = loginConfig.sendTime) !== null && _e !== void 0 ? _e : DEFAULT_SEND_TIME;
        this._noElk = (_f = loginConfig.noElk) !== null && _f !== void 0 ? _f : this._noElk;
        this._sendHistoryLog();
        this._sendDevice();
        this._interval = this._initInterval();
        this._initLogPanel();
    }
    /**
     * 设置userId和token
     * @params userId
     * @params token
     */
    _setUserIdAndToken(userId, token) {
        setToken(token);
        setUserId(userId);
    }
    _initLogPanel() {
        window.__vtuber_monitor_console_by_key = (key) => {
            logVisualDataInConsoleOne(this._localStorage.getAllData(), key);
        };
        window.__vtuber_monitor_console = () => {
            logVisualData(this._localStorage.getAllData(), this._createTime, VisualLogType.console);
        };
        window.__vtuber_monitor_page = () => {
            logVisualData(this._localStorage.getAllData(), this._createTime, VisualLogType.page);
        };
        if (getQueryString()) {
            logVisualData(this._localStorage.getAllData(), this._createTime, VisualLogType.page);
        }
    }
    // 初始化发送间隔
    _initInterval() {
        return setInterval(() => {
            this._sendLogToServer(this._localStorage.getNeedSendData());
        }, this._sendTime);
    }
    /**
     * 根据baseUrl初始化http
     */
    _initHttp(baseUrl) {
        initHttp(baseUrl);
    }
    // 发送给后端前处理数据
    _beforeSendHandleData(data) {
        const newData = [];
        const tempItems = new Map();
        data.forEach(item => {
            var _a;
            // 处置完成的数据认为发送完毕
            item.needSendServer = false;
            // 定义serverTag，没有加serverTag的统计数量
            const serveKey = `${item.logType}_${item.msg.serveKey}`;
            // 初始化
            const tempItem = (_a = tempItems.get(serveKey)) !== null && _a !== void 0 ? _a : Object.assign(Object.assign({}, item), { msg: Object.assign({}, item.msg), num: 0 });
            // 第一次不执行
            if (tempItem.num) {
                switch (item.msg.msgType) {
                    // 平均值和时间都取均值
                    case MsgType.average:
                    case MsgType.time:
                        tempItem.msg.msg = handleAverage(tempItem.msg.msg, tempItem.num, item.msg.msg);
                        break;
                    // 累计值
                    case MsgType.count:
                        tempItem.msg.msg += item.msg.msg;
                        break;
                    // 最大值
                    case MsgType.max:
                        tempItem.msg.msg = handleMax(tempItem.msg.msg, item.msg.msg);
                        break;
                    // 最小值
                    case MsgType.min:
                        tempItem.msg.msg = handleMin(tempItem.msg.msg, item.msg.msg);
                        break;
                }
            }
            // 数量累计
            tempItem.num++;
            tempItems.set(serveKey, tempItem);
        });
        tempItems.forEach(value => {
            if ([MsgType.object, MsgType.text].includes(value.msg.msgType)) {
                newData.push(Object.assign(Object.assign({}, value), { msg: Object.assign(Object.assign({}, value.msg), { serverTag: Object.assign({}, value.msg.serverTag), serveKey: value.logType, msg: value.num, msgType: MsgType.count }) }));
            }
            else {
                newData.push(value);
            }
        });
        this._localStorage.saveData();
        return newData;
    }
    // 发送历史未发送的数据
    _sendHistoryLog() {
        this._sendLogToServer(this._localStorage.getHistoryneedSendServerData());
    }
    // 发送给性能监控
    _sendToMetric(data) {
        let serverType = null;
        switch (data.msg.msgType) {
            case MsgType.time:
                serverType = ServerLogType.timer;
                break;
            case MsgType.count:
                serverType = ServerLogType.counter;
                break;
            case MsgType.average:
            case MsgType.max:
            case MsgType.min:
                serverType = ServerLogType.guage;
                break;
        }
        serverType &&
            data.msg.serveKey &&
            sendLogApi({
                type: serverType,
                name: `${this._metrixPrefix}_${data.msg.serveKey}`,
                amount: Number(data.msg.msg) % 1 === 0 ? Number(data.msg.msg) : +Number(data.msg.msg).toFixed(2),
                tags: Object.assign({}, data.msg.serverTag),
            });
    }
    // 发送给前端日志中心
    _sendToMonitor(data) {
        sendElkApi({
            level: data.logType,
            data: JSON.stringify({
                msg: data.msg.msg,
                tips: data.msg.msgTip,
            }),
        });
    }
    _sendDevice() {
        sendLogApi({
            type: ServerLogType.counter,
            name: `${this._metrixPrefix}_device_info`,
            amount: 1,
            tags: {
                device: device.type,
                os: device.os,
            },
        });
    }
    // 发送给后端
    _sendLogToServer(data) {
        this._beforeSendHandleData(data).forEach(item => {
            if (item.msg.serveKey) {
                this._sendToMetric(item);
            }
            if (!this._noElk) {
                this._sendToMonitor(item);
            }
        });
    }
    /**
     * 收集日志到监控sdk
     * @param data 其中的showInPanel代表了是否发送给elk日志中心，拥有serverTag会发送给中台后端，api调用不许要加serverTag，会自动统计然后发给中台后端
     * @param immediate 立即发送给后端
     * @param noCache 不放到storage
     */
    sendLog(data, immediate = false, noCache = false) {
        console.log('sendlog',data)
        var _a, _b;
        const logData = Object.assign(Object.assign({}, data), { 
            // 默认发送，设置needSendServer为false即不发送，设置nextSend即下次启动时发送
            needSendServer: !data.nextSend && ((_a = data.needSendServer) !== null && _a !== void 0 ? _a : true), nextSend: (_b = data.nextSend) !== null && _b !== void 0 ? _b : false, time: +new Date() });
        if (!noCache) {
            this._localStorage.addData(logData);
        }
        if (immediate && logData.needSendServer) {
            this._sendLogToServer([logData]);
        }
        else {
            this._localStorage.saveData();
        }
    }
    /**
     * 立即发送所有数据给服务器
     */
    sendAllCacheToServer() {
        this.endSendToServer();
        this._sendLogToServer(this._localStorage.getNeedSendData());
        this.startSendToServer();
    }
    /**
     * 停止给服务端发送数据
     */
    endSendToServer() {
        if (this._interval) {
            clearInterval(this._interval);
            this._interval = null;
        }
    }
    /**
     * 开始给服务端发送数据
     */
    startSendToServer() {
        this._interval = this._initInterval();
    }
    /**
     * 销毁
     */
    dispose() {
        this.endSendToServer();
        window.__vtuber_monitor_console = null;
        window.__vtuber_monitor_console_by_key = null;
        window.__vtuber_monitor_page = null;
    }
}

export { LogType, MsgType, ServerLogType, VisualLogType, MonitorSDK as default };
